package cn.iocoder.yudao.module.call.api.client.dto;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.call.enums.CallResultTypeEnum;
import cn.iocoder.yudao.module.call.utils.TimeUtil;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * 外呼话单推送实体类
 */
@Data
public class CallNotifyDTO {

    private String type;            // bill, task

    private Integer calleeAmount;   // 号码总数
    private Integer remainAmount;   // 剩余数量

    // 0.未启动；
    // 1.运行中；
    // 2.已暂停；
    // 3.已停止
    private Integer status;         // 任务状态

    // 请求唯一标识
    private String reqNo;

    private String tempRecordUrl;

    private String recordUrl;

    private Integer callSecond;

    private Integer callMinute;

    // 呼叫开始时间
    private LocalDateTime startTime;
    // 应答时间
    private LocalDateTime answerTime;

    // 挂断/结束时间
    private LocalDateTime endTime;

    // 结果码： success=成功， fail=失败, leak=漏接,illegal=错误
    private String resultCode;

    private Integer resultType;

    private String resultMsg;

    // 三方订单号
    private String userData;

    private boolean isBatchTask;

    private String batchTaskId;
    // 坐席工号，需要注意的是，如果是未接通状态， stuffNo是空的
    private String staffNo;
    // 被叫号码
    private String callee;

    // 90. 呼叫失败，系统线路问题
    private static final List<Integer> SYSTEM_ERROR = ListUtil.of(15, 16, 18, 511);
    // 91. 未接通
    private static final List<Integer> DISCONNECT = ListUtil.of(1213, 1210, 1211, 610, 510, 310, 0, 110, 210, 410, 710, 911, 912, 1010, 810, 1110, 1111);
    // 92. 空号
    private static final List<Integer> EMPTY_NUMBER = ListUtil.of(615, 611, 311, 1, 13, 18, 211, 111, 411, 711);
    // 93. 客户拒接
    private static final List<Integer> REJECT = ListUtil.of(612, 312, 2, 5, 6, 112, 124, 212, 126, 412, 712, 717, 718, 724, 726, 512);
    // 94. 客户忙，未接听
    private static final List<Integer> CUSTOMER_BUSY = ListUtil.of(1215, 1214, 1112, 613, 614, 313, 314, 214, 213, 3, 4, 113, 114, 121, 122, 123, 413, 414, 713, 714, 811, 812, 813, 913, 914, 1011, 1012, 513, 514);
    // 95. 坐席忙或未接听
    private static final List<Integer> AGENT_BUSY = ListUtil.of(1216, 1212, 607, 608, 604, 605, 606, 321, 322, 323, 324, 320, 7, 8, 9, 10, 19, 17, 14, 120, 125, 415, 416, 720, 721, 722, 723, 725, 910);
    private static final List<Integer> SUCCESS = ListUtil.of(1300, 1301, 1201, 1200, 1100, 1101, 1000, 1001, 719, 501, 301, 300, 11, 12, 100, 101, 200, 201, 202, 400, 401, 700, 701, 800, 801, 900, 901, 1300, 1301, 1400, 1401, 1500, 1501, 600, 601, 500, 603, 602);

    // 10 播放语音时挂断
    private static final List<Integer> HANG_UP_DURING_VOICE = ListUtil.of(715, 115, 315);
    // 11 播放语音后挂断
    private static final List<Integer> HANG_UP_AFTER_VOICE = ListUtil.of(716, 116);

    public static CallNotifyDTO ofSimpleCallCallback(String reqNo, String resultCode, Integer resultType, String tempRecordUrl, Integer callSecond, String startTime, String answerTime, String endTime, String staffNo, String callee) {
        CallNotifyDTO dto = new CallNotifyDTO();
        dto.setType("bill");
        dto.setReqNo(reqNo);
        dto.setBatchTask(false);
        dto.setCallSecond(callSecond);
        dto.setResultCode(resultCode);
        dto.setStaffNo(staffNo);
        dto.setCallee(callee);

        if (StrUtil.isNotEmpty(tempRecordUrl)) {
            dto.setTempRecordUrl("https://haiwei.org.cn" + tempRecordUrl);
        }
        dto.setResultType(convertResultType(resultType));
        dto.setCallMinute(TimeUtil.secondToMin(callSecond));
        //放音类型在放音时挂断了,也算接通
        if ((Objects.equals(dto.getResultType(), CallResultTypeEnum.HANG_UP_DURING_VOICE.getValue()) || Objects.equals(dto.getResultType(), CallResultTypeEnum.HANG_UP_AFTER_VOICE.getValue()) && dto.getCallSecond() > 0)
        ) {
            dto.setResultCode("success");
        }
        // 修复接听时间话单转化的问题。
        if (StrUtil.isNotEmpty(startTime)) {
            try {
                dto.setStartTime(LocalDateTimeUtil.parse(startTime, DatePattern.NORM_DATETIME_FORMATTER));
            } catch (Exception e) {
                dto.setStartTime(null);
            }
        }
        if (StrUtil.isNotEmpty(answerTime)) {
            try {
                dto.setAnswerTime(LocalDateTimeUtil.parse(answerTime, DatePattern.NORM_DATETIME_FORMATTER));
            } catch (Exception e) {
                dto.setAnswerTime(null);
            }
        }
        if (StrUtil.isNotEmpty(endTime)) {
            try {
                dto.setEndTime(LocalDateTimeUtil.parse(endTime, DatePattern.NORM_DATETIME_FORMATTER));
            } catch (Exception e) {
                dto.setEndTime(null);
            }
        }
        return dto;
    }

    public static CallNotifyDTO ofBatchTaskCallback(String reqNo, String taskId, String resultCode, Integer resultType, String tempRecordUrl, Integer callSecond, String startTime, String answerTime, String endTime, String stuffNo, String callee) {
        CallNotifyDTO dto = ofSimpleCallCallback(reqNo, resultCode, resultType, tempRecordUrl, callSecond, startTime, answerTime, endTime, stuffNo, callee);
        dto.setBatchTask(true);
        dto.setBatchTaskId(taskId);
        return dto;
    }


    public static CallNotifyDTO of(boolean isBatchTask, String batchTaskId, String reqNo, String resultCode, Integer resultType, String tempRecordUrl, Integer callSecond, String startTime, String answerTime, String endTime, String staffNo, String callee) {
        if (isBatchTask) {
            return ofBatchTaskCallback(reqNo, batchTaskId, resultCode, resultType, tempRecordUrl, callSecond, startTime, answerTime, endTime, staffNo, callee);
        }
        return ofSimpleCallCallback(reqNo, resultCode, resultType, tempRecordUrl, callSecond, startTime, answerTime, endTime, staffNo, callee);
    }

    // 转换resultType
    public static Integer convertResultType(Integer srcResultType) {
        // 先处理几个失败情况的
        // 10. 播放语音时挂断
        if (CollUtil.contains(HANG_UP_DURING_VOICE, srcResultType)) {
            return CallResultTypeEnum.HANG_UP_DURING_VOICE.getValue();
        }
        // 11. 播放语音完挂断
        if (CollUtil.contains(HANG_UP_AFTER_VOICE, srcResultType)) {
            return CallResultTypeEnum.HANG_UP_AFTER_VOICE.getValue();
        }
        // 90. 呼叫失败，系统线路问题
        if (CollUtil.contains(SYSTEM_ERROR, srcResultType)) {
            return CallResultTypeEnum.SYSTEM_ERROR.getValue();
        }
        // 91. 未接通
        if (CollUtil.contains(DISCONNECT, srcResultType)) {
            return CallResultTypeEnum.DISCONNECT.getValue();
        }
        // 92. 空号
        if (CollUtil.contains(EMPTY_NUMBER, srcResultType)) {
            return CallResultTypeEnum.EMPTY_NUMBER.getValue();
        }
        // 93. 客户拒接
        if (CollUtil.contains(REJECT, srcResultType)) {
            return CallResultTypeEnum.REJECT.getValue();
        }
        // 94. 客户忙，未接听
        if (CollUtil.contains(CUSTOMER_BUSY, srcResultType)) {
            return CallResultTypeEnum.CUSTOMER_BUSY.getValue();
        }
        // 95. 坐席忙或未接听
        if (CollUtil.contains(AGENT_BUSY, srcResultType)) {
            return CallResultTypeEnum.AGENT_BUSY.getValue();
        }
        // 成功的 1
        if (CollUtil.contains(SUCCESS, srcResultType)) {
            return CallResultTypeEnum.SUCCESS.getValue();
        }
        return CallResultTypeEnum.FAIL.getValue();
    }
}
